#pragma once
#include "common.hpp"
#include "log.hpp"
#include "addr.hpp"
static int cd = 10;
class Socket
{
public:
    Socket() {}
    // 虚函数全部重写：
    virtual void Csocket() = 0;
    virtual void Bind(const uint16_t &port) = 0;
    virtual void Listen(int n = cd) = 0;
    virtual shared_ptr<Socket> Accept(inetaddr *client) = 0;
    virtual int Recv(string &bf) = 0;
    virtual void Send(string &mess) = 0;
    virtual int Connect(string ip, uint16_t port) = 0;
    virtual void Close() = 0;
    ~Socket() {}
    // 服务端初始化sock：
    void arrangesock(const uint16_t &port) // 直接继承过去
    {
        Csocket();
        Bind(port);
        Listen();
    }
    // 客户端初始化sock：
    void clientsock()
    {
        Csocket();
    }
};

class Tcpsocket : public Socket
{

public:
    // 子类重写完的虚表（编译填充相关信息）
    Tcpsocket(int fd = -1) : _sockfd(fd) {}
    void Csocket() override
    {
        _sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_sockfd < 0)
        {
            use_log(loglevel::DEBUG) << "socket failure!";
            exit(SOCKET_ERR);
        }
        use_log(loglevel::DEBUG) << "socket success!";
    }
    void Bind(const uint16_t &port) override
    {
        inetaddr addr(port);
        int n = bind(_sockfd, (sockaddr *)addr.addrptr(), addr.addrlen());
        if (n < 0)
        {
            use_log(loglevel::DEBUG) << "bind failure!";
            exit(BIND_ERR);
        }
        use_log(loglevel::DEBUG) << "bind success!";
    }
    void Listen(int n = cd) override
    {

        int m = listen(_sockfd, cd);
        if (m < 0)
        {
            use_log(loglevel::DEBUG) << " listen failure!";
            exit(LISTEN_ERR);
        }
        use_log(loglevel::DEBUG) << "listen success!";
    }
    shared_ptr<Socket> Accept(inetaddr *client) override // 输出型参数
    {
        sockaddr_in ar;
        socklen_t len = sizeof(ar);//原结构体大小16字节
        int wrsock = ::accept(_sockfd, (sockaddr *)&ar, &len);
        //len输入出型参数：可能存在变长变量修改ar结构体大小（告知读取多少进结构体）；len也可能会改变（不同环境的sockaddr_in结构体大小不同，len应及时被调整做输出参数返回）
        if (wrsock < 0)
        {
            use_log(loglevel::DEBUG) << " accept  failure!";
            return nullptr;
        }
        use_log(loglevel::DEBUG) << " accept  success!";
        client->setinetaddr(ar);
        return make_shared<Tcpsocket>(wrsock); // 多态应用
    }

    void Close() override
    {
        ::close(_sockfd); // ：：防止命名空间污染；使用系统自己的函数等
    }
    int Recv(string &bf) override
    {
        char buff[1024];
        int n = ::recv(_sockfd, buff, sizeof(buff) - 1, 0); // 权限默认设为0:阻塞式
        // flags：这是 recv 特有的参数，用于设置一些额外的接收选项，例如 MSG_DONTWAIT 表示非阻塞接收，MSG_PEEK 表示查看数据但不将其从接收队列中移除等。

        if (n > 0)

        {
            buff[n] = 0;
            bf += buff;
            use_log(loglevel::DEBUG) << " 成功读取！ ";
        }
        return n;
    }
    void Send(string &mess) override
    {
        send(_sockfd, mess.c_str(), mess.size(), 0);
        use_log(loglevel::DEBUG) << " 成功发送！ ";
    }
    int Connect(string ip, uint16_t port) override
    {
        inetaddr ir(ip, port);
        int n = connect(_sockfd, (sockaddr *)ir.addrptr(), ir.addrlen());
        if (n < 0)
        {
            use_log(loglevel::DEBUG) << "connet failure!";
            return n;
        }
        use_log(loglevel::DEBUG) << "connet success!";
        return 0;
    }
    ~Tcpsocket() {}

private:
    int _sockfd;
};